﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;
using System.Threading;
using Serilog;
using System.Diagnostics;
using System.Threading.Channels;
using System.Runtime.Remoting.Channels;
using System.Diagnostics.Eventing.Reader;


using EasyTest.Shared.TestAttribute;
using EasyTest.Shared.Extensions;
using EasyTest.Shared.外部访问;
using EasyTest.Shared.EnumType;


namespace ZLGCANoptimize
{
    public class Can
    {
        [DllImport("seedAndKey.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        private static extern int GenerateKeyEx(
            [In] byte[] iSeedArray,
            uint iSeedArraySize,
            uint iSecurityLevel,
            byte[] iVariant,
            [In, Out] byte[] ioKeyArray,
            uint iKeyArraySize,
            out uint oSize
        );
        //static List<ZCAN_Receive_Data> zCAN_Receive_Datas = null;
        //static ZLGCANHelper zLGCANHelper = null;  //注释掉此全局静态参数，更改为局部参数的方式，否则多通道方式下，可能非反射调用，可能会互相影响,2024-11-14

        //string 远程IP = "192.168.1.50";
        //int 类型 = 52;
        //int 远程Port = 8989;
        //int 本地Port = 8000;

        static bool open;//设备打开状态

        [ExposedMethodAttribute("")]
        public bool 唤醒(int 通道, out string 信息)
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }

                bool result1, result2;
                 _ = zLGCANHelper.RecvData(通道, 0, 100, 100);
                for (int i = 0; i < 1; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        result2 = zLGCANHelper.SentData(通道, 0x1F1, "02 00 00 80 02 00 00 00", true, SendType.正常发送);
                        Thread.Sleep(60);
                        result1 = zLGCANHelper.SentData(通道, 0x4C0, "00 00 00 00 00 00 00 00", true, SendType.正常发送);
                        Thread.Sleep(60);
                        result2 = zLGCANHelper.SentData(通道, 0x1F1, "02 00 00 80 02 00 00 00", true, SendType.正常发送);
                        Thread.Sleep(60);
                        if ((!result1 || !result2) && i > 5)
                        {
                            信息 = "发送数据失败,唤醒失败";
                            return false;
                        }
                    }
                    List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0, 10, 1000);
                    string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
                    if (datas.Length > 10)
                    {
                        信息 = "唤醒成功";
                        return true;
                    }
                }
                //3、关闭
                信息 = "唤醒失败";
                return false;

            }
            catch (Exception ex)
            {
                信息 = "唤醒失败" + ex.Message;
                return false;
            }
        }
        /// <summary>
        /// 唤醒_极速模式
        /// </summary>
        /// <param name="通道"></param>
        /// <param name="信息"></param>
        /// <returns></returns>
        [ExposedMethodAttribute("")]
        public bool 唤醒_极速模式(int 通道, out string 信息)
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }

                bool result1, result2;
                _ = zLGCANHelper.RecvData(通道, 0, 100, 100);
                for (int j = 0; j < 3; j++)
                {
                    result2 = zLGCANHelper.SentData(通道, 0x1F1, "02 00 00 80 02 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(30);
                    result1 = zLGCANHelper.SentData(通道, 0x4C0, "00 00 00 00 00 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(30);
                    result2 = zLGCANHelper.SentData(通道, 0x1F1, "02 00 00 80 02 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(30);
                    if ((!result1 || !result2) && j >= 3)
                    {
                        信息 = "发送数据失败,唤醒失败";
                        return false;
                    }
                }
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0, 10, 500);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
                if (datas.Length > 10)
                {
                    信息 = "唤醒成功";
                    return true;
                }

                信息 = "唤醒失败";
            }
            catch (Exception ex)
            {
                信息 = "唤醒失败" + ex.Message;
            }
            return false;
        }
        //[ExposedMethodAttribute("")]
        //public static bool 解密(int 通道, out string 信息, string 安全等级 = "01")
        //{
        //    try
        //    {
        //        if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
        //        {
        //            信息 = "启动can设备失败";
        //            return false;
        //        }
        //        var EntryMode = CanFactory.EntryMODE(通道, zLGCANHelper, zCAN_Receive_Datas, 安全等级);
        //        foreach (var item in EntryMode)
        //        {
        //            if (item.Key == false)
        //            {
        //                信息 = "解密失败:" + item.Value;
        //                return false;
        //            }
        //        }
        //        信息 = "解密成功";
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        信息 = "解密失败：" + ex.Message;
        //        return false;
        //    }
        //}
        public static bool 解密(int 通道, List<ZCAN_Receive_Data> zCAN_Receive_Datas, out string 信息, string 安全等级 = "01")
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    eLog.AddLog($"解密失败，启动can设备失败",eMsgType.Error);
                    return false;
                }
                var EntryMode = CanFactory.EntryMODE(通道, zLGCANHelper, zCAN_Receive_Datas, 安全等级);
                foreach (var item in EntryMode)
                {
                    if (item.Key == false)
                    {
                        eLog.AddLog($"解密失败:" + item.Value, eMsgType.Error);
                        信息 = "解密失败:" + item.Value;
                        return false;
                    }
                }
                信息 = "解密成功";
                return true;
            }
            catch (Exception ex)
            {
                信息 = "解密失败：" + ex.Message;
               // LogHelper.Error($"[3E.解密]解密异常，{ex.Message}，{ex.StackTrace}");
                eLog.AddLog($"[3E.解密]解密异常，{ex.Message}，{ex.StackTrace}", eMsgType.Error);
                return false;
            }
        }
     
        public bool 读取SN_F18C_多次模式(int 通道, out string SN, out int SN字节, out string 信息)
        {

            信息 = "";
            SN = "";
            SN字节 = SN.Length;
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }
                for (int i = 0; i < 3; i++)
                {
                    List<ZCAN_Receive_Data> zCAN_Receive_Datas = new List<ZCAN_Receive_Data>();
                    SN = CanFactory.GetSN(通道, zLGCANHelper, zCAN_Receive_Datas, out 信息).Trim();
                    if (!string.IsNullOrWhiteSpace(SN))
                    {
                        SN字节 = SN.Trim().Length;
                        return true;
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                信息 = ex.Message;
                SN = "";
                //LogHelper.Error($"[3E.读取SN_多次模式]异常，{ex.Message}，{ex.StackTrace}");
                eLog.AddLog($"[3E.读取SN_多次模式]异常，{ex.Message}，{ex.StackTrace}", eMsgType.Error);
                if (ex.InnerException != null && !string.IsNullOrWhiteSpace(ex.InnerException.Message))
                {
                    // LogHelper.Error($"[3E.读取SN_多次模式]内部异常，{ex.Message}，{ex.StackTrace}");
                    eLog.AddLog($"[3E.读取SN_多次模式]内部异常，{ex.Message}，{ex.StackTrace}", eMsgType.Error);
                }
                return false;
            }
        }
       
        [ExposedMethodAttribute("")]
        public bool 自动打开360(int 通道, out string 信息)
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }

                int count = 3;
                bool result;
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0, 100, 100);
                for (int j = 0; j < count; j++)
                {
                    result = zLGCANHelper.SentData(通道, 0x1F5, "00 00 00 01 00 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(60);
                    if (!result && j + 1 >= count)
                    {
                        信息 = "发送数据失败,自动打开360失败";
                        return false;
                    }
                }

                信息 = "自动打开360成功";
                return true;
            }
            catch (Exception ex)
            {
                信息 = "自动打开360失败" + ex.Message;
            }
            return false;
        }
        [ExposedMethodAttribute("")]
        public bool 自动打开360_01(int 通道, out string 信息)
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }

                int count = 3;
                bool result;
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0, 100, 100);
                for (int j = 0; j < count; j++)
                {
                    result = zLGCANHelper.SentData(通道, 0x1F5, "00 00 00 01 00 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(60);
                    if (!result && j + 1 >= count)
                    {
                        信息 = "发送数据失败,自动打开360失败";
                        return false;
                    }
                }

                信息 = "自动打开360成功";
                return true;
            }
            catch (Exception ex)
            {
                信息 = "自动打开360失败" + ex.Message;
            }
            return false;
        }
        [ExposedMethodAttribute("")]
        public bool 自动打开360_02(int 通道, out string 信息)
        {
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }

                int count = 3;
                bool result;
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0, 100, 100);
                for (int j = 0; j < count; j++)
                {
                    result = zLGCANHelper.SentData(通道, 0x1F5, "00 00 00 02 00 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(60);
                    if (!result && j + 1 >= count)
                    {
                        信息 = "发送数据失败,自动打开360失败";
                        return false;
                    }
                }

                信息 = "自动打开360成功";
                return true;
            }
            catch (Exception ex)
            {
                信息 = "自动打开360失败" + ex.Message;
            }
            return false;
        }
        [ExposedMethodAttribute("")]
        public bool 写入360恢复默认值C002(int 通道, out string 信息, out string data)
        {
            data = "";

            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";
                    return false;
                }
                _ = zLGCANHelper.RecvData(通道, 0x769, 1000, 100);
                bool OK = Can.解密(通道, new List<ZCAN_Receive_Data>(), out 信息);
                if (!OK)
                {
                    信息 = "解密失败";
                    return false;
                }
                /*
                    10 09 2E 4C 00 02 00 00
                    21 00 00 00 00 00 00 00
                 */
                string 首帧 = "07 2E C0 02 FF FF FF FF";//
                bool result1;
                result1 = zLGCANHelper.SentData(通道, 0x761, 首帧, true, SendType.正常发送);
                if (!result1)
                {
                    信息 = "发送数据失败,360恢复默认值失败";
                    return false;
                }
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0x769, 3, 500);

                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);// 03 6E 4C 10 AA AA AA AA
                data = string.Join(",", datas);
                if (datas.Length > 0)
                {
                    foreach (string s in datas)
                    {
                        if (s.Trim().StartsWith("03 6E"))//03 6E 4C 00 AA AA AA AA
                        {
                            信息 = "360恢复默认值成功";
                            return true;
                        }
                    }
                }

                信息 = "360恢复默认值失败";
            }
            catch (Exception ex)
            {
                信息 = "360恢复默认值失败" + ex.Message;
            }
            return false;

        }
        [ExposedMethodAttribute("")]
        public bool 读取360数据C002(int 通道, out string 数据C002, out string 信息)
        {
            数据C002 = "";

            信息 = "";
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";// "06 2E F1 8B 24 07 26 00";
                    return false;
                }
                _ = zLGCANHelper.RecvData(通道, 0x769, 300, 100);
                Thread.Sleep(50);
                bool r1 = false, r2 = false;
                for (int i = 0; i < 5; i++)
                {
                    r1 = zLGCANHelper.SentData(通道, 0x761, "03 22 C0 02 00 00 00 00", true, SendType.正常发送);
                    Thread.Sleep(50);
                    r2 = zLGCANHelper.SentData(通道, 0x761, "30 08 14 00 00 00 00 00", true, SendType.正常发送);
                    if (r1 && r2)
                    {
                        break;
                    }
                }
                if (!r1 || !r2)
                {
                    信息 = "发送失败...";
                    数据C002 = 信息;
                    return false;
                }
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0x769, 3, 1500);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);

                string[] hexValues = new string[5];
                int num = 0;
                bool ok10 = false;
                bool ok21 = false;
                foreach (string s in datas)
                {
                    ok10 = true;
                    for (int i = 0; i < s.Split(' ').Length; i++)
                    {
                        if (i < 4 || i > 7) continue;
                        hexValues[num] = s.Split(' ')[i];
                        num++;
                    }
                }

                信息 = string.Join(",", datas);
                数据C002 = String.Join("", hexValues);
                return ok10;

            }
            catch (Exception ex)
            {
                信息 = ex.Message;
                throw;
            }
            return true;
        }


        //=================================== 2024-09-27 ELO指令更新，以下方法为对应更新的内容 ==========================================
        [ExposedMethodAttribute("")]
        public bool 写入SNF18C(int 通道, string sn, out string 信息)
        {
            List<string> list = new List<string>()
            {
                "30", "30", "30", "30", "30", "30", "30", "30",
                "30", "30","30","30","30","30","30","30","30",
            };
            try
            {
                if (!数据.初始化(通道, out ZLGCANHelper zLGCANHelper))
                {
                    信息 = "启动can设备失败";//2E  写，22读
                    return false;
                }
                bool OK = Can.解密(通道, new List<ZCAN_Receive_Data>(), out 信息,"61");
                if (!OK)
                {
                    信息 = "解密失败";
                    return false;
                }
                /*
                   10 13 2E F1 8C 20 37 46
                   21 30 35 32 38 43 52 36 
                   22 32 36 30 30 30 35 00
                 */
                list.InsertRange(0, sn.ToHexArray());//10 13 2E F1 8C 20 32  33 
                string str1 = $"10 13 2E F1 8C 20 " + String.Join(" ", list.GetRange(0, 2)).Trim();
                string str2 = $"21 " + String.Join(" ", list.GetRange(2, 7)).Trim();
                string str3 = $"22 " + String.Join(" ", list.GetRange(9, 6)).Trim() + " AA";

                //bool result1, result2, result3, result4;
                bool result1, result3, result4;
                result1 = zLGCANHelper.SentData(通道, 0x761, str1, true, SendType.正常发送);
                //Thread.Sleep(50);
                //result2 = zLGCANHelper.SentData(通道, 0x761, "30 00 00 00 00 00 00 00", true, SendType.正常发送);
                Thread.Sleep(50);
                result3 = zLGCANHelper.SentData(通道, 0x761, str2, true, SendType.正常发送);
                Thread.Sleep(50);
                result4 = zLGCANHelper.SentData(通道, 0x761, str3, true, SendType.正常发送);
                Thread.Sleep(50);
                string 返回 = "";
                for (int i = 0; i < 3; i++)
                {
                    List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(通道, 0x769, 1);
                    string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
                    返回 = string.Join(" ", datas);
                    if (返回.Contains("03 6E"))
                    {
                        信息 = "写入SN数据成功";
                        return true;
                    }
                    Thread.Sleep(50);
                }

                信息 = "写入SN数据失败:" + 返回;
            }
            catch (Exception ex)
            {
                信息 = "写入SN失败:" + ex.Message;
            }
            return false;
        }
    }
}
